﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DBAccessLibrary.Interface;
using DBAccessLibrary.Model;
using DataAccess;

namespace DBAccessLibrary.Grammar
{
    class OleGrammar : DBGrammar, IGrammar, ILocalGrammar
    {
        public OleGrammar(ConnectionModel connect)
            : base(connect)
        { }

        private string GetTypeFilter(FieldEntity field, string sql)
        {
            string typeStr = field.TypeName;
            int columnLength;
            int.TryParse(field.Length, out columnLength);
            string length = field.Length;
            string TypeName = field.TypeName.ToUpper();
           

            if (TypeName == "TIMESTAMP" || TypeName == "DATE")
            {
                length = "";
            }
            if (!field.IsNull)
            {
                sql += " Not Null";
            }
            return string.Format(sql, field.TableName, field.Name, typeStr, length);
        }
        #region IGrammar 成员

        public string AddColumn(Model.FieldEntity field)
        {
            string sql = "ALTER TABLE [{0}] ADD COLUMN {1} {2}{3}";
                  
            
            if (!string.IsNullOrEmpty(field.DefaultValue))
            {
                sql += " DEFAULT " + field.DefaultValue;
            }
            return GetTypeFilter(field, sql);
        }

        public IEnumerable<string> EditColumn(Model.FieldEntity field)
        {
            List<string> sql = new List<string>();

            sql.Add(GetTypeFilter(field, "ALTER TABLE {0} ALTER COLUMN {1} SET DATA TYPE {2}{3}"));

            if (!string.IsNullOrEmpty(field.DefaultValue))
            {

            }

            return sql;
        }

        public IEnumerable<string> RemoveColumn(Model.FieldEntity field)
        {
            List<string> list = new List<string>();
            list.Add(string.Format("ALTER TABLE {0} DROP COLUMN {1}", field.TableName, field.TransName));
            
                  
            return list;
        }

        public IEnumerable<string> EditPrimary(Model.TableEntity table)
        {
            List<string> sql = new List<string>();
            string pk = table.PrimaryKeyName;
              string[] parimaryKey = table.FileNodes.Where(o => o.IsPrimaryKey).Select(o => o.Name).ToArray();
              if (parimaryKey.Length > 0)
              {
                  //删除约束
                  if (!string.IsNullOrEmpty(pk))
                  {
                      string drop = string.Format("alter table {0} drop constraint {1} ", table.Name, pk);
                      sql.Add(drop);
                  }
                  else
                  {
                      pk = "PK" + parimaryKey[0];
                  }
                  sql.Add(string.Format("ALTER TABLE {0} ADD CONSTRAINT {1} PRIMARY KEY({2})", table.Name, pk, string.Join(",", parimaryKey)));
              }
            return sql;
        }

        public string SelectTop(Model.TableEntity table, int count)
        {
            string sql =  "SELECT TOP {1} * FROM [{0}]";
                   
            return string.Format(sql, table.TransName, count);
        }

        public string GetChTableSql
        {
            get { return string.Empty; }
        }

        public string IsExistChTableSql
        {
            get { return string.Empty; }
        }

        public string AppendTabText(string text)
        {
            return base.TabText(text);
        }

        public string GetErrorInfo(string errorMsg)
        {
            return string.Empty;
        }

        public string GetProcParamInfo(Model.ProcEntity entity)
        {
            if (entity == null)
                return string.Empty;
            string sql;
            if (entity.ChildNodes.Count > 0)
            {
                List<string> list = new List<string>();
                foreach (ProcParamEntity param in entity.ChildNodes)
                {
                    if (param.Status == "IN")
                    {
                        list.Add(string.Format("{0}[{1}({2})]", Environment.NewLine, param.Name, param.TypeName));
                    }
                    else
                    {
                        list.Add(string.Format("{0}[{1}({2})-OUT]", Environment.NewLine, param.Name, param.TypeName));
                    }
                }
                sql = "(" + string.Join(",", list.ToArray()) + ")";
            }
            else
            {
                sql = "()";
            }
            return string.Format("{0} {1}{2}",
                                 "EXEC",
                                 entity.Name,
                                 sql);
        }



     
        public string GetPageingSql(string sql, decimal index, decimal count)
        {
            return sql;
        }

        #endregion

        #region ILocalGrammar 成员

        public DataAccess.DatabaseType GetConnectionStr(out string connectStr)
        {
            connectStr = _connect.ConnectionStr; 
           
            return DatabaseType.OleDBSupported;
             
        }

        #endregion
    }
}
